﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ConcreteMappersAndObjects.DomainObjects;
using DataMappers;
using System.Data;


namespace ConcreteMappersAndObjects.Mappers
{
    public class ExamsDataMapper : AbstractDataMapper<int, Exam>
    {

        private IEntityMapper<int, CUnit> _cunitsMapper;
        private IEntityMapper<RoomExamKey, RoomExam> _roomExamsMapper;
        private IEntityMapper<int, ExamSeason> _seasonsMapper;

        public void SetCUnitsMapper(IEntityMapper<int, CUnit> mapper) { _cunitsMapper = mapper; }
        public void SetRoomsMapper(IEntityMapper<RoomExamKey, RoomExam> mapper) { _roomExamsMapper = mapper; }
        public void SetExamSeasonsMapper(IEntityMapper<int, ExamSeason> mapper){_seasonsMapper = mapper;}
        
        protected override int GetKeyFrom(System.Data.SqlClient.SqlDataReader sdr)
        {
            return sdr.GetInt32(0);
        }

        protected override string DoGetAllStatement()
        {
            return "select ID, CUnitID, ExamDate, ExamSeasonID, ExamEndDate, Scheduled from Exams";
        }

        protected override string DoGetFindStatement()
        {
            return DoGetAllStatement() + " where ID = @ID";
        }

        protected override void BindFindStatement(System.Data.SqlClient.SqlCommand cmd, int key)
        {
            cmd.Parameters.AddWithValue("@ID", key);
        }

        private class ExamsFilter : IFilter
        {
            private int _examKey;
            public ExamsFilter(int examKey) { _examKey = examKey; }
            #region IFilter Members

            public string GetWhereClause()
            {
                return " where ExamID = @ExamID";
            }

            public void BindValues(System.Data.SqlClient.SqlCommand cmd)
            {
                cmd.Parameters.AddWithValue("@ExamID", _examKey);
            }

            #endregion
        }


        protected override Exam DoLoad(System.Data.SqlClient.SqlDataReader sdr)
        {
            int key = GetKeyFrom(sdr);
            ConcreteValueHolder<int, CUnit> cunit = new ConcreteValueHolder<int,CUnit>(sdr.GetInt32(1), _cunitsMapper);
            LazySet<RoomExamKey, RoomExam> rooms = new LazySet<RoomExamKey, RoomExam>(_roomExamsMapper, new ExamsFilter(key));
            ConcreteValueHolder<int, ExamSeason> season = new ConcreteValueHolder<int, ExamSeason>(sdr.GetInt32(3), _seasonsMapper);
            return new Exam(key, cunit, rooms, sdr.GetDateTime(2), sdr.GetDateTime(4),season, sdr.GetBoolean(5)); 
        }

        protected override string GetUpdateCommand()
        {
            return "update Exams set CUnitID = @CUnitID, ExamDate = @ExamDate, ExamSeasonID = @ExamSeasonID, ExamEndDate = @ExamEndDate, Scheduled = @Scheduled where ID = @ID";
        }

        protected override void DoBindUpdate(System.Data.SqlClient.SqlCommand cmd, Exam t)
        {
            cmd.Parameters.Add("@CUnitID", SqlDbType.Int).Value = t.CUnit.ID;
            cmd.Parameters.Add("@ExamDate", SqlDbType.DateTime).Value = t.ExamDate;
            cmd.Parameters.Add("@ExamSeasonID", SqlDbType.Int).Value = t.Season.ID;
            cmd.Parameters.Add("@ExamEndDate", SqlDbType.DateTime).Value = t.ExamEndDate;
            cmd.Parameters.Add("@Scheduled", SqlDbType.Bit).Value = t.Scheduled;
            cmd.Parameters.Add("@ID", SqlDbType.Int).Value = t.ID;
        }

        protected override string GetInsertCommand()
        {
            return "ExamInsert";
        }

        protected override void DoBindInsert(System.Data.SqlClient.SqlCommand cmd, Exam t)
        {
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.Parameters.Add("@CUnitID", SqlDbType.Int).Value = t.CUnit.ID; // Validar existencia de CUNIT?
            cmd.Parameters.Add("@ExamDate", SqlDbType.DateTime).Value = t.ExamDate;
            cmd.Parameters.Add("@ExamEndDate", SqlDbType.DateTime).Value = t.ExamEndDate;
            cmd.Parameters.Add("@ExamSeasonId", SqlDbType.Int).Value = t.Season.ID;
            cmd.Parameters.Add("@Scheduled", SqlDbType.Bit).Value = t.Scheduled;
        }

        protected override string GetRemoveCommand()
        {
            return "delete from Exams where ID = @ID";
        }

        protected override void DoBindRemove(System.Data.SqlClient.SqlCommand cmd, Exam t)
        {
            cmd.Parameters.Add("@ID", SqlDbType.Int).Value = t.ID;
        }

        protected override void FinishUpdateObject(Exam t)
        {
            
        }

        protected override void FinishNewObject(Exam t, object id)
        {
            t.ID = Convert.ToInt32(id);
        }

        protected override void FinishDeleteObject(Exam t)
        {
        
        }
    }
}
